home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / ms_dos / div / all next >
Text File  |  1993-11-30  |  32KB  |  1,058 lines

  1. # DIVIDE_START=update.doc
  2. ・「-s」オプションの導入。「静かに!」実行する。
  3. -------------------------- div001f --------------------------
  4. 1993.8.6
  5. ・ディレクトリ指定のファイルの検索のバグを修正。
  6. ・フリコレ7応募版。
  7.  
  8. 1993.7.19
  9. ・「-u」において、「削除しない」を選択すると戻り値が1で終了するようにした。
  10.  
  11. -------------------------- div001e --------------------------
  12. 1993.6.22
  13. ・新しいオプションを追加した。
  14.  「-a:xxxxx」部分のファイルから1つにまとめたファイルを作る。(追加モード)
  15.  
  16. -------------------------- div001d --------------------------
  17. 1993.6.21
  18.  「-u:xxxxx」オプションの際、拡張子によって部分ファイル名を記述する行の制御
  19. を追加した。本日追加したのは、「*.bat」である。
  20.  
  21. 1993.5.24
  22.  「-u:xxxxx」オプションの際、拡張子によって部分ファイル名を記述する行の制御
  23. を追加した。本日追加したのは、「*.plt」と「*.plp」である。いずれも、MopT
  24. ermのパイロットの拡張子である。(FAPXのファイルということ)
  25.  
  26. -------------------------- div001c --------------------------
  27.  プロテクトモードのプログラムにした。
  28.  
  29. -------------------------- div001b --------------------------
  30. 1993.5.18
  31. ・新しいオプションを追加した。
  32.  「-u:xxxxx」部分のファイルから1つにまとめたファイルを作る。
  33.  
  34. 1993.3.30
  35. ・新しいオプションを追加した。
  36.  「-n」新しいファイルを作る。*.new というファイルが作られる。
  37. ・内部処理を少し変更した。「-o:」オプションが設定されている時は、古い方のフ
  38.  ァイルの部分ファイルを検索しないようにした。
  39. ・部分ファイルを検索した時、見つかった数を表示するうよにした。
  40.  
  41. 1993.3.28
  42. ・「/* INCLUDE=xxxxx」を展開しないオプションを追加した。
  43.  -i-
  44.  
  45. 1993.3.21
  46. ・「-o:xxxxx」スイッチを指定すると *.old というファイルは出力しないように
  47.  した。
  48.  また、出力するファイル名の指定にワイルドカードを可能にした。
  49. ・分割ファイル名の比較に、ファイル名を大文字として比較することにした。
  50.  MS-DOS の仕様に合わせたということ。
  51. ・「update.doc」の追加。(忘れていた)
  52.  
  53. -------------------------- div001a --------------------------
  54. 1993.3.19
  55. ・FFMHOB のデータライブラリー4番に登録された。
  56.  
  57. # DIVIDE_END
  58.  
  59. # -DIVIDE_START=div.ggg
  60. ======================================================================
  61. 【ソフト  名】  DIV.EXE ファイル分割プログラム          Version 0.01f
  62. 【登  録  名】  div001f.lzh (LHAで解凍して下さい)
  63. 【検索  キー】  1:DIV
  64. 【著作権  者】  山先  GHH01217
  65. 【開発  環境】  Turbo-C Ver2.0  →  div.exe
  66. 【対応  機種】  MS-DOS 汎用
  67. 【動作  確認】  FM-TOWNS20F + 8M-RAM  コンソール上
  68. 【公  開  日】  93/05/24
  69. 【ソフトウェア種別】 プログラミングツール。フリー・ソフトウェア。
  70. ======================================================================
  71. 【ソフト紹介】
  72.  Cの分割されたソースを一本化した際、再度分割するのを支援するプログラムです。
  73.  
  74.  LHAを使って解凍すると、div.exe というファイルと all というファイルが出来
  75. ます。そこで、「div all」とすると、ドキュメントファイル等が出てきます。
  76.  使い方は、div.doc をお読み下さい。
  77.  変更点については、update.doc をお読み下さい。
  78.  
  79.  ダウンロードファイル名を  div001f.lzh   として下さい。
  80.                                               GHH01217  山先
  81. # DIVIDE_END
  82.  
  83. /* DIVIDE_START=div.doc */
  84.   ■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□
  85.   ファイル分割ツール DIV.EXE の使い方
  86.                                 div.doc
  87.   ■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□
  88.  
  89. 1.DIV.EXEとは
  90.    C言語の特徴の1つとして、分割コンパイルが可能ということがあります。
  91.   1つのプログラムを作るのに1つのソースファイルだけで全体が記述してあ
  92.   るというようなプログラムであると、「ちょっと修正」という場合にでも、
  93.   ソースファイルを全部をエディタに読み込んでエディットし、コンパイルし
  94.   なければなりません。時間がかかってしまうということになります。
  95.    そこで、ソースファイルを機能ごとに分割し、それぞれを別々に記述し、
  96.   別々にコンパイルして、最終的に1つのプログラムにするという手法がとら
  97.   れました。「分割コンパイルが可能」ということです。
  98.    ところが、この分割コンパイルでプログラムを記述していると、非常にた
  99.   くさんのファイルが作られることになります。そして、きちんと仕様を決定
  100.   しないで安易にプログラムを作っていると、機能の変更とか追加の場合に修
  101.   正が大変になってしまうことがあります。例えば、重複して「static」な変
  102.   数を定義していたり、ほとんど同じ様な機能の関数を定義していたりします。
  103.   また、新しい変数や関数を導入する場合、それまでの変数名や関数名を変更
  104.   した場合もあります。そのような場合、ファイルが1つであると、逆に便利
  105.   である場合もあります。
  106.    市販のエディタにVzというエディタがあります。安価であるのに非常に
  107.   優秀なエディタでありまして、大きなファイルでも、非常に高速に文字列を
  108.   検索したり置換したりできます。このエディタを使用していると、文字列の
  109.   置換のために別のプログラムを起動しなくても充分実用になります。
  110.    ということは、逆に、分割されたファイルを1つに纏めたり、再度分割で
  111.   きたりするプログラムがあれば良いことになります。そこで作ったのが本プ
  112.   ログラムです。
  113.  
  114.    さて、複数のファイルを1つにまとめる場合、いろんな手法でまとめるこ
  115.   とができると思います。1つは、纏めたファイルとは別に「どこに」「どの
  116.   ような」ファイルがあるかという、いわばインデックスのファイルを用意し
  117.   て、それでそれぞれのファイルを管理するというやり方です。あるいは、1
  118.   つに纏めたファイルの中に、ソースファイル中には現れそうにないコードや
  119.   文字列を挿入しておくという方法もあります。
  120.    本プログラムでは、その第2の方法としてソースファイルには現れそうに
  121.   ない文字列を1つに纏めたファイルの中に挿入し、その文字列を探索するこ
  122.   とを通して、ファイルの区切りとしています。また、1つに纏めたファイル
  123.   の拡張子を「.old」とした別のファイルを作り、そのファイルとの一致・不
  124.   一致を調べることによって修正が「あった」「なかった」を判断しています。
  125.  
  126. 2.DIVが識別する、区切りの文字列
  127.   (1) CTは、次の文字列を行の頭から記述してあると、そこから新しいファイ
  128.   ルが始まると判断します。
  129.         /* DIVIDE_START=          (a)
  130.         /* -DIVIDE_START=         (b)
  131.         # DIVIDE_START=           (c)
  132.         # -DIVIDE_START=          (d)
  133.         ; DIVIDE_START=           (e)
  134.         ; -DIVIDE_START=          (f)
  135.    これらの文字列の後ろにファイル名を記述しておきます。ファイル名の後
  136.   ろの文字列は無視されます。例えば次のように指定します。
  137.          /* DIVIDE_START=div.doc */
  138.    ファイル名の長さは32バイトまでとしています。存在しないディレクト
  139.   リをファイル名の中に記述してあると、エラーで処理が中断されますので、
  140.   注意して下さい。
  141.  
  142.   (2) また、次の文字列が行の頭から記述してあると、そこでそのファイルは終
  143.   了したと判断します。
  144.        /* DIVIDE_END */
  145.        # DIVIDE_END
  146.        ; DIVIDE_END
  147.  
  148.   (3) 更に、ファイルの途中に、次の文字列があると、挿入複写の操作を行い
  149.   ます。
  150.          /* INCLUDE=
  151.  
  152.   (4) これらの文字列は、普通、分割するファイルの中に複写されます。しか
  153.   し、(1)の(b)(d)(f) の場合のように「DIVIDE_START」の前にハイフン「-」
  154.   を入れることにより、これらの区切りの文字列を複写しないように指定する
  155.   ことができます。
  156.  
  157.  
  158. 3.DIVの起動の仕方
  159.   (1) 1つに纏めたファイルから分割する場合
  160.    これは、非常に簡単です。1つに纏めたファイルの名前を「all」とする
  161.   と、
  162.          div all
  163.    とするだけで、区切りの文字列を探索してファイルを分割します。
  164.    この場合、DIVは同じファイル名で拡張子が「.old」のファイル(
  165.   「all.old」)を探します。もしそのファイルがないと、DIVは、「all」
  166.   から、全てのファイルを切り出します。もしそのファイルがあると、その中
  167.   のファイルと一致・不一致をチェックして、一致しないファイルだけを書き
  168.   出します。
  169.    そして、最後に「all」を「all.old」に上書きします。これで、次回の
  170.   「div all」に備えることができます。
  171.  
  172.   (2) 分割したファイルを1つに纏める場合
  173.    これには、大きく2つの方法があります。いずれの場合も、纏めるファイ
  174.   ルを指定しなければなりません。纏め先のファイルも指定しなければなりま
  175.   せん。
  176.  
  177.    纏め方の第1は、纏め先に無条件に指定のファイルを追加する方法です。
  178.   次のように指定します。
  179.          div -a:*.c all
  180.    こうすると、カレント・ディレクトリの拡張子が「.c」のファイルが全て
  181.   「all」というファイルの後ろに追加されます。追加するファイルが「all」
  182.   に含まれているかどうかはチェックしていませんので、注意して使用して下
  183.   さい。
  184.  
  185.    第2の方法は、次のようにします。
  186.          div -u:*.c all
  187.    これも、上の方法と殆ど同じになりますが、唯一異なるのは「all」とい
  188.   うファイルがあった場合の処理が異なるということです。上の「-a」では単
  189.   純に「all」というファイルに追加するだけだったのですが、この場合は
  190.   「all」というファイルがあった場合は、それを削除して良いかどうかを尋
  191.   ねて来ます。そこで、「y」と入力すると「all」というファイルは削除され、
  192.   拡張子「.c」のファイルが「all」に追加されていきます。また、「n」と入
  193.   力すると、処理は中断され、戻り値が1で終了します。
  194.    この、戻り値が1で終了することを利用して、次のようなバッチファイル
  195.   を作って1つに纏めたファイルを作ると便利です。
  196.          rem update.bat
  197.              div -u:*.c all
  198.              if errorlevel 1 goto end
  199.              div -a:*.h all
  200.              div -a:*.doc all
  201.              div -a:makefile all
  202.          :end
  203.  
  204.   (3) 使用例
  205.    例として、このプログラムのソース等を一本化したファイルを添付してあ
  206.   るので、それを分割してみて下さい。
  207.    使い方
  208.      div  all
  209.  
  210.    また、「div」とだけ入力するとオプションの指定が表示されます。
  211.  
  212.  
  213.   ★★★★★★★
  214. 4.★★ 注意 ★★
  215.   ★★★★★★★
  216.  
  217.    分割するファイル名の指定を間違えると、元のファイルが削除されてしま
  218.   うので、注意して下さい。例えば、「all」という1つに纏めたファイルの
  219.   中に「all」という分割するファイルがあったりすると………
  220.  
  221. 5.著作権
  222.    本プログラムはNIFTY-ID:GHH01217 山先(やません)
  223.   に著作権があるものとします。しかし、その使用、配付は自由に行っていた
  224.   だいてかまいません。
  225.  
  226.  
  227. 6.何かありましたら。
  228.  私あてメールを下さい。
  229.                        GHH01217 山先
  230. /* DIVIDE_END */
  231.  
  232. # -DIVIDE_START=m.bat
  233. echo off
  234. :loop
  235.     if        "%1"==""    goto    main
  236.     vz        %1
  237. :loop2
  238.     make
  239.     if        errorlevel    1        goto    error
  240.     goto    end
  241. :main
  242.     vz        all
  243.     div        all
  244.     goto    loop2
  245. :error
  246.     pause
  247.     goto loop
  248. :end
  249. # DIVIDE_END
  250.  
  251. # -DIVIDE_START=listlibs
  252. e:\tc\lib\mylib e:\tc\lib\emu e:\tc\lib\maths e:\tc\lib\cs
  253. # DIVIDE_END
  254.  
  255. # DIVIDE_START=makefile
  256. COM_VERSION1    =    0
  257. COM_VERSION2    =    01f
  258. VERSION        =    $(COM_VERSION1)$(COM_VERSION2)
  259. tc            =    tcc
  260. lib            =    tlib
  261. link        =    tlink
  262. cflags        =    -ms -A -d -N -O -DVERSION="$(COM_VERSION1).$(COM_VERSION2)"
  263.  
  264. .c.obj    :
  265.     $(tc)    -c $(cflags) -Ie:\tc\include $*
  266.  
  267. .c.com    :
  268.     $(tc)    $(cflags) -Ie:\tc\include $*
  269.     $(link)    /c \tc\lib\c0t.obj $*.obj , $* , nul , @listlibs
  270.  
  271. com_prg        =    div.exe
  272.  
  273. hdr1        =    \tc\include\mylib.h
  274. obj1        =    main.obj
  275.  
  276. $(com_prg)    :    $(obj1) makefile $(hdr1)
  277.     tlink    /c \tc\lib\c0s.obj $(obj1) , $* , nul , @listlibs
  278.     copy    $(com_prg) d:\exe
  279.     lha        u    $*$(VERSION) *.exe all
  280.  
  281. $(obj1)        : $(hdr1) makefile
  282. # DIVIDE_END
  283.  
  284. /* DIVIDE_START=main.c */
  285. /*
  286.     ファイル分割ツール                                    div.doc
  287.  
  288.             作 : 山先(NIFTY-ID:GHH01217)
  289. */
  290.  
  291. #include    <mylib.h>
  292. #include    <ctype.h>
  293. #include    <string.h>
  294. #include    <dos.h>
  295. #include    <dir.h>
  296.  
  297. #define        MAX_FILENAME_LEN    32
  298. #define        MAX_BUFSIZE            (1024*20)
  299.  
  300. struct    DIV    {
  301.             char    file[ MAX_FILENAME_LEN ];
  302.             long    seek;
  303. };
  304.  
  305. #define        MAX_DIV        400
  306. static    struct    DIV        div_new[ MAX_DIV ] , div_old[ MAX_DIV ];
  307. static        int        max_new_div , max_old_div;
  308.  
  309. static        FILE    *fpi , *fps , *fpo , *fpl;
  310. static        char    outfile[ MAX_FILENAME_LEN ];
  311. static        char    new_file[ MAX_FILENAME_LEN ];
  312. static        char    old_file[ MAX_FILENAME_LEN ];
  313. static        char    new_file_name[ MAX_FILENAME_LEN ];
  314. static        char    str[ MAX_BUFSIZE ];
  315. static        int        line_number;
  316. static        char    list_file_name[ MAX_FILENAME_LEN ];
  317. static        int        list_file_sw = FALSE;
  318. static        int        make_new_file = FALSE;
  319.  
  320. #define    MAX_OUT_FILES    20
  321. static        char    out_files[ MAX_OUT_FILES ][ MAX_FILENAME_LEN ];
  322. static        int        max_out_files = 0;
  323. static        int        out_option_line_sw = TRUE;
  324.  
  325. static        int        verify = FALSE;
  326. static        int        without_include = FALSE;
  327.  
  328. #define    mess_check    if ( verify == TRUE )
  329.  
  330. static    void    useage()
  331. {
  332.     printf( "ファイル分割ツール\n\t%s\tversion=%s by ... 山先(GHH01217)"
  333.             "\n\n使い方:div [-option] file名"
  334.             "\n options ="
  335.             "\n  -l:xxxxx ・・・・・・・ 出力ファイルのリスト"
  336.             "\n  -o:xxxxx ・・・・・・・ 出力するファイルの指定"
  337.             "\n  -u:xxxxx ・・・・・・・ 部分ファイルから1つにまとめたファイル"
  338.                                     "を作る"
  339.             "\n  -a:xxxxx ・・・・・・・ 部分ファイルから1つにまとめたファイル"
  340.                                     "を作る(追加モード)"
  341.             "\n  -v ・・・・・・・・・・・・・ 途中経過の表示"
  342.             "\n  -i- ・・・・・・・・・・・・ INCLUDE 指定を無視する"
  343.             "\n  -n ・・・・・・・・・・・・・ 部分ファイルの名前の順に"
  344.                                     "新しいファイルを作る。"
  345.             , str
  346.             , VERSION
  347.     );
  348. }
  349.  
  350. static    char    *last_comma( char *str )
  351. {
  352.     char    *result;
  353.  
  354.     result = str;
  355.     while ( *str ) {    if ( *str == '.' ) result = str;
  356.                         str++;
  357.     };    return( result );
  358. }
  359.  
  360. static    char    *last_yen( char *str )
  361. {
  362.     char    *result;
  363.  
  364.     result = str;
  365.     while ( *str ) {    if ( *str == '\\' ) result = str;
  366.                         str++;
  367.     };    return( result );
  368. }
  369.  
  370. static    void    set_list_file( char *file )
  371. {
  372.     if ( *file != ':' ) {
  373.         printf( "\nオプションの指定が間違っています <%s>" , file );
  374.         exit( 1 );
  375.     };
  376.     file++;
  377.     strcpy( list_file_name , file );
  378.     list_file_sw = TRUE;
  379. }
  380.  
  381. static    void    set_out_files( char *file )
  382. {
  383.     int        c;
  384.     char    *p;
  385.     
  386.     if ( *file != ':' ) {
  387.         printf( "\nオプションの指定が間違っています <%s>" , file );
  388.         exit( 1 );
  389.     };
  390.     if ( max_out_files >= MAX_OUT_FILES ) {
  391.         printf( "\n出力するファイルの指定が多すぎます → "
  392.                 "最大で %d です" , MAX_OUT_FILES
  393.         );
  394.         exit( 1 );
  395.     };
  396.     file++;
  397.     while( *file ) {
  398.         if ( max_out_files >= MAX_OUT_FILES ) {
  399.             printf( "\n出力するファイルの指定が多すぎます → "
  400.                     "最大で %d です" , MAX_OUT_FILES
  401.             );
  402.             exit( 1 );
  403.         };
  404.         p = out_files[ max_out_files ];
  405.         while(    ( *file != ',' )
  406.         &&        ( ! isspace( *file ) )
  407.         &&        ( *file != '\0' )
  408.         ) {
  409.             c = *file++;
  410.             *p++ = toupper( c );    /* 大文字にして格納する */
  411.         };
  412.         if ( p != out_files[ max_out_files ] ) {
  413.             *p = '\0';
  414.             max_out_files++;
  415.         };
  416.         if (    ( *file == ',' )
  417.         ||        isspace( *file )
  418.         ) {
  419.             file++;
  420.         };
  421.     };
  422. }
  423.  
  424. static    void    set_include_opt( char *opt )
  425. {
  426.     if ( *opt == '-' ) {
  427.         without_include = TRUE;        return;
  428.     };
  429. }
  430.  
  431. static    void    set_options( char *opt )
  432. {
  433.     switch( *opt ) {
  434.         case 'l':    set_list_file( opt + 1 );        break;
  435.         case 'o':    set_out_files( opt + 1 );        break;
  436.         case 'v':    verify = TRUE;                    break;
  437.         case 'i':    set_include_opt( opt + 1 );        break;
  438.         case 'n':    make_new_file = TRUE;            break;
  439.     };
  440. }
  441.  
  442. static    void    main_loop_include( char *file )
  443. {
  444.     FILE    *fpi2;
  445.  
  446.     if ( without_include == TRUE )    return;
  447.  
  448.     if ( ( fpi2 = fopen( file , "r" ) ) == NULL ) {
  449.         printf( "\n<%s>が見つかりません" , file );
  450.         return;
  451.     };
  452.     while ( fgets( str , MAX_BUFSIZE , fpi2 ) != NULL ) {
  453.         fprintf( fpo , "%s" , str );    line_number++;
  454.     };
  455.     fclose( fpi2 );
  456. }
  457.  
  458. static    void    get_file_name( char *str , char *out_file )
  459. {
  460.     char    *p;
  461.  
  462.     p = str;        while (   isspace( *p ) ) p++;
  463.     strcpy( out_file , p );
  464.     p = out_file;    while ( ! isspace( *p ) ) p++;
  465.     *p = '\0';
  466.     p = out_file;    while ( *p ) *p++ = toupper( *p );
  467. }
  468.  
  469. static    int        isEquFile_sub( const char *name1 , const char *name2 )
  470. {
  471.     while ( *name2 ) {
  472.         if ( *name2 == '*' )    return( YES );
  473.         if ( *name2 != '?' ) {
  474.             if ( *name1 != *name2 )    return( NO );
  475.         };
  476.         name1++;    name2++;
  477.     };
  478.     if ( *name1 == *name2 )    return( YES );
  479.     return( NO );
  480. }
  481.  
  482. static    int        isEquFile( const char *file1 , char *file2 )
  483. {
  484.     char    name1[ MAX_FILENAME_LEN ] , name2[ MAX_FILENAME_LEN ];
  485.     char    *p1 , *p2;
  486.     
  487.     p1 = last_yen( file1 );    if ( *p1 == '\\' ) p1++;
  488.     p2 = name1;
  489.     while( *p1 && *p1 != '.' ) *p2++ = *p1++;        *p2 = '\0';
  490.     p1 = last_yen( file2 );    if ( *p1 == '\\' ) p1++;
  491.     p2 = name2;
  492.     while( *p1 && *p1 != '.' ) *p2++ = *p1++;        *p2 = '\0';
  493.     if ( isEquFile_sub( name1 , name2 ) == NO )        return( NO );
  494.     /* 拡張子の比較 */
  495.     p1 = last_comma( file1 );    if ( *p1 == '.' ) p1++;
  496.     p2 = name1;
  497.     while( *p1 ) *p2++ = *p1++;                        *p2 = '\0';
  498.     p1 = last_comma( file2 );    if ( *p1 == '.' ) p1++;
  499.     p2 = name2;
  500.     while( *p1 ) *p2++ = *p1++;                        *p2 = '\0';
  501.     if ( isEquFile_sub( name1 , name2 ) == NO )        return( NO );
  502.     return( YES );
  503. }
  504.  
  505. static    int        check_file_name( const char *out_file )
  506. {
  507.     int        i;
  508.  
  509.     if ( max_out_files == 0 )                                    return( TRUE );
  510.     for ( i = 0 ; i < max_out_files ; i++ ) {
  511.         if ( isEquFile( out_file , out_files[ i ] ) == YES )    return( TRUE );
  512.     };
  513.     return( FALSE );
  514. }
  515.  
  516. struct    DIVIDE_LINE    {
  517.             char    *name;
  518.             int        len;
  519. };
  520.  
  521. struct    DIVIDE_LINE    divide_line[] = {
  522.     /*   123456789 123456789 */
  523.     {    "/* DIVIDE_START="    ,    16    },
  524.     {    "/* -DIVIDE_START="    ,    17    },
  525.     {    "# DIVIDE_START="    ,    15    },
  526.     {    "# -DIVIDE_START="    ,    16    },
  527.     {    "; DIVIDE_START="    ,    15    },
  528.     {    "; -DIVIDE_START="    ,    16    },
  529.     {    "REM DIVIDE_START="    ,    17    },
  530.     {    "REM -DIVIDE_START=",    18    }
  531. };
  532.  
  533. static    int
  534. isStartLine( char *str , int *keta )
  535. {
  536.     int    i;
  537.     
  538.     for( i=0 ; i<sizeof(divide_line) ; i++ ) {
  539.         if ( strncmp( str , divide_line[i].name , divide_line[i].len ) == 0 ) {
  540.             *keta = divide_line[ i ].len;
  541.             return( TRUE );
  542.         };
  543.     };
  544.     return( FALSE );
  545. }
  546.  
  547. static    int
  548. isDivideEnd( const char *str )
  549. {
  550.                     /*   123456789 1234567 */
  551.     if ( strncmp( str , "/* DIVIDE_END */" , 16 ) == 0 )    return( TRUE );
  552.     if ( strncmp( str , "# DIVIDE_END" ,     12 ) == 0 )    return( TRUE );
  553.     if ( strncmp( str , "; DIVIDE_END" ,     12 ) == 0 )    return( TRUE );
  554.     if ( strncmp( str , "REM DIVIDE_END" ,   14 ) == 0 )    return( TRUE );
  555.     return( FALSE );
  556. }
  557.  
  558. static    void    main_loop_sub( int new )
  559. {
  560.     char    *p;
  561.  
  562.     p = div_new[ new ].file;
  563.     if ( check_file_name( p ) != TRUE )        return;
  564.  
  565.     if ( ( fpo = fopen( p , "w" ) ) == NULL ) {
  566.         printf( "\n<%s>を書き込みの為にオープンできません" , p );
  567.         return;
  568.     };
  569.     fpi = fopen( new_file , "r" );
  570.     fseek( fpi , div_new[ new ].seek , SEEK_SET );
  571.     fgets( str , MAX_BUFSIZE , fpi );
  572.     if (    strncmp( str , "/* -DIVIDE_START=" , 17 ) == 0
  573.     ||        strncmp( str , "# -DIVIDE_START="  , 16 ) == 0
  574.     ||        strncmp( str , "; -DIVIDE_START="  , 16 ) == 0
  575.     ||        strncmp( str , "REM -DIVIDE_START=", 18 ) == 0
  576.     ) {
  577.         out_option_line_sw = FALSE;
  578.     } else {
  579.         out_option_line_sw = TRUE;
  580.     };
  581.     printf( "\n<%-13s>を分割 " , p );
  582.     line_number = 0;
  583.  
  584.     if ( out_option_line_sw == TRUE ) {
  585.         fprintf( fpo , "%s" , str );
  586.         line_number++;
  587.     };
  588.     while ( fgets( str , MAX_BUFSIZE , fpi ) != NULL ) {
  589.         if ( isDivideEnd( str ) == TRUE )    break;
  590.         fprintf( fpo , "%s" , str );    line_number++;
  591.         /*                   123456789 123 */
  592.         if ( strncmp( str , "/* INCLUDE=" , 11 ) == 0 ) {
  593.             get_file_name( str + 11 , outfile );
  594.             main_loop_include( outfile );
  595.         };
  596.     };
  597.     if ( out_option_line_sw == TRUE ) {
  598.         fprintf( fpo , "%s" , str );    /* DIVIDE_END の行 */
  599.         line_number++;
  600.     };
  601.     fclose( fpo );    fclose( fpi );
  602.     printf( " %4d 行" , line_number );
  603. }
  604.  
  605. static    void
  606. set_struct_div_end( FILE *fpi , int ptr , int count , struct DIV *div )
  607. {
  608.     get_file_name( str + ptr , div[ count ].file );
  609.     if ( count >= MAX_DIV ) {
  610.         printf( "\nファイル中の部分ファイルの数が多すぎて処理できません。"
  611.                 "(最大=%d)" , MAX_DIV
  612.         );
  613.         exit( 1 );
  614.     };
  615.     while ( fgets( str , MAX_BUFSIZE , fpi ) != NULL ) {
  616.         /*                   123456789 123456 */
  617.         if ( isDivideEnd( str ) == TRUE )    break;
  618.     };
  619. }
  620.  
  621. int        Sort( const struct DIV *div1 , const struct DIV *div2 )
  622. {
  623.     return( strcmp( div1->file , div2->file ) );
  624. }
  625.  
  626. static    int        set_struct_div( const char *file , struct DIV *div )
  627. {
  628.     FILE    *fpi;
  629.     int        i , count , keta;
  630.  
  631.     if ( ( fpi = fopen( file , "r" ) ) == NULL ) return( 0 );
  632.     count = 0;
  633.     div[ count ].seek = ftell( fpi );
  634.     while ( fgets( str , MAX_BUFSIZE , fpi ) != NULL ) {
  635.         if ( isStartLine( str , &keta ) == TRUE ) {
  636.             set_struct_div_end( fpi , keta , count , div );
  637.             count++;
  638.         };
  639.         div[ count ].seek = ftell( fpi );
  640.     };
  641.     fclose( fpi );
  642.     qsort( (char *)div , count , sizeof( struct DIV ) , Sort );
  643.     /* 同じ物がないかチェックする */
  644.     for( i = 0 ; i < count - 1 ; i++ ) {
  645.         if ( strcmp( div[ i ].file , div[ i + 1 ].file ) == 0 ) {
  646.             printf( "\n部分ファイルの名前で、同じ名前<%s>があるので処理"
  647.                     "できません"
  648.                     "\nどれかを削除して下さい"
  649.                     "\n\n\t処理を中断します\n" , div[ i ].file
  650.             );
  651.             exit( 1 );
  652.         };
  653.     };
  654.     return( count );
  655. }
  656.  
  657. static    int        isOldDiv( int new )
  658. {
  659.     int        i;
  660.     char    *p;
  661.     
  662.     p = div_new[ new ].file;
  663.     for ( i = 0 ; i < max_old_div ; i++ ) {
  664.         if ( strcmp( p , div_old[ i ].file ) == 0 ) {
  665.             /* 一致した → 古いファイルにある */
  666.             return( i );
  667.         };
  668.     };
  669.     return( -1 );    /* 古いファイルにはない */
  670. }
  671.  
  672. static    int        isEqu( int new , int old )
  673. {
  674.     int        result;
  675.     char    str2[ 2048 ];
  676.  
  677.     fpi = fopen( new_file , "r" );    fps = fopen( old_file , "r" );
  678.     fseek( fpi , div_new[ new ].seek , SEEK_SET );
  679.     fseek( fps , div_old[ old ].seek , SEEK_SET );
  680.     result = FALSE;
  681.     while ( fgets( str , MAX_BUFSIZE , fpi ) != NULL ) {
  682.         if ( fgets( str2 , 2048 , fps ) == NULL )        break;
  683.         if ( strcmp( str , str2 ) != 0 )                break;
  684.         if ( isDivideEnd( str ) == TRUE ) {
  685.             result = TRUE;
  686.             break;
  687.         };
  688.     };
  689.     fclose( fpi );    fclose( fps );
  690.     return( result );
  691. }
  692.  
  693. static    void    prEqu()
  694. {
  695.     int        new , old , equ;
  696.  
  697.     printf( "\n以下の部分ファイルが見つかりました\n" );
  698.     new = old = 0;
  699.     while ( new < max_new_div ) {
  700.         if ( old >= max_old_div )    break;
  701.         equ = strcmp( div_new[ new ].file , div_old[ old ].file );
  702.         if ( equ == 0 ) {
  703.             /* 同じ部分ファイルがある場合 */
  704.             color( WHITE );
  705.             printf( "%-13s\t" , div_new[ new ].file );
  706.             new++;    old++;
  707.         } else if ( equ < 0 ) {
  708.             /* 新の方が小さい場合 */
  709.             color( GREEN );
  710.             while ( strcmp( div_new[ new ].file , div_old[ old ].file ) < 0 ) {
  711.                 printf( "%-13s\t" , div_new[ new ].file );
  712.                 new++;
  713.                 if ( new >= max_new_div )    break;
  714.             };
  715.         } else {
  716.             /* 新の方が大きい場合 */
  717.             color( YELLOW );
  718.             while ( strcmp( div_new[ new ].file , div_old[ old ].file ) > 0 ) {
  719.                 printf( "%-13s\t" , div_old[ old ].file );
  720.                 old++;
  721.                 if ( old >= max_old_div )    break;
  722.             };
  723.         };
  724.     };
  725.     color( GREEN );
  726.     while ( new < max_new_div ) {
  727.         printf( "%-13s\t" , div_new[ new ].file );
  728.         new++;
  729.     };
  730.     color( WHITE );
  731. }
  732.  
  733. static    void    make_old_file( char *new_file , char *old_file )
  734. {
  735.     size_t    size;
  736.  
  737.     printf( "\n新しいファイルのコピー作成 %s → %s " , new_file , old_file );
  738.     fpi = fopen( new_file , "rb" );    fps = fopen( old_file , "wb" );
  739.     while( ( size = fread(str,sizeof(char),MAX_BUFSIZE,fpi) ) == MAX_BUFSIZE){
  740.         fwrite( str , sizeof( char ) , size , fps );
  741.     };
  742.     fwrite( str , sizeof( char ) , size , fps );
  743.     fclose( fpi );    fclose( fps );
  744.     printf( "終了" );
  745. }
  746.  
  747. static    void    main_loop( const char *file )
  748. {
  749.     int        i , old , copy_sw;
  750.     char    *p1 , *p2;
  751.  
  752.     if ( strlen( file ) >= MAX_FILENAME_LEN ) {
  753.         printf(    "\n ただ今の仕様で、指定のファイル名の長さは %d バイトまで"
  754.                 "となっています。"
  755.                 "\n 申し訳ありませんがディレクトリを移動して実行して下さい。",
  756.                 MAX_FILENAME_LEN
  757.         );
  758.         exit( 1 );
  759.     };
  760.  
  761.     /* ファイル名を設定しておく */
  762.     strcpy( new_file , file );    strcpy( old_file , file );
  763.     p1 = last_yen( old_file );    p2 = last_comma( p1 );
  764.     if ( p1 != p2 ) *p2 = '\0';            /* 拡張子を削除する */
  765.     strcat( old_file , ".old" );        /* 拡張子を old にする */
  766.  
  767.     printf( "\n<%-13s>から部分ファイルを検索 " , file );
  768.     max_new_div = set_struct_div( file , div_new );
  769.     printf( "(%d) 終了" , max_new_div );
  770.     if ( max_new_div == 0 ) {
  771.         printf( "\n<%s>が見つかりません。" , file );
  772.         return;
  773.     };
  774.     
  775.     /**************************************************************/
  776.     /* 部分ファイル名に元のファイル名が入っていないかチェックする */
  777.     /**************************************************************/
  778.     for ( i=0 ; i < max_new_div ; i++ ) {
  779.         if ( strcmp( file , div_new[ i ].file ) == 0 ) {
  780.             printf(    "\n 部分ファイル名の中に元のファイル名と"
  781.                     "同じファイル名のものがあります。"
  782.                     "\n 分割すると元のファイルが削除されてしまうおそれが"
  783.                     "あります。"
  784.                     "\n 処理を中断します"
  785.             );
  786.             exit( 1 );
  787.         };
  788.     };
  789.  
  790.     if ( make_new_file == TRUE ) {
  791.         p1 = last_comma( old_file );    *p1 = '\0';
  792.         strcat( old_file , ".new" );
  793.         if ( ( fpo = fopen( old_file , "a" ) ) == NULL ) {
  794.             printf( "\n<%s>を書き込みの為にオープンできません" , old_file );
  795.             return;
  796.         };
  797.         fpi = fopen( new_file , "r" );
  798.         line_number = 0;
  799.         printf( "\n<%s>を作ります" , old_file );
  800.         for ( i = 0 ; i < max_new_div ; i++ ) {
  801.             fseek( fpi , div_new[ i ].seek , SEEK_SET );
  802.             while ( fgets( str , MAX_BUFSIZE , fpi ) != NULL ) {
  803.                 fprintf( fpo , "%s" , str );    line_number++;
  804.                 /* divide_end という行を書き出してから終了判定を行う */
  805.                 if ( isDivideEnd( str ) == TRUE )    break;
  806.             };
  807.             fprintf( fpo , "\n" );    /* 1行空ける */
  808.         };
  809.         printf( " %4d 行 終了" , line_number );
  810.         fclose( fpo );    fclose( fpi );
  811.         return;
  812.     };
  813.  
  814.     copy_sw = FALSE;
  815.     if ( max_out_files == 0 ) {
  816.         /* 古い方のファイルから部分ファイルを取り出す */
  817.         printf( "\n<%-13s>から部分ファイルを検索 " , old_file );
  818.         max_old_div = set_struct_div( old_file , div_old );
  819.         printf( "(%d) 終了" , max_old_div );
  820.         /* 部分ファイルの表示 */
  821.         mess_check    prEqu();
  822.         for( i = 0 ; i < max_new_div ; i++ ) {
  823.             if ( access( div_new[ i ].file , 0 ) != 0 ) {
  824.                 /* ディレクトリ上にファイルにはない */
  825.                 main_loop_sub( i );        copy_sw = TRUE;
  826.             } else if ( ( old = isOldDiv( i ) ) < 0 ) {
  827.                 /* 古いファイルにはない → 追加された */
  828.                 main_loop_sub( i );        copy_sw = TRUE;
  829.             } else if ( isEqu( i , old ) != TRUE ) {
  830.                 /* 古いファイルにある   → 内容チェック */
  831.                 /* 内容が変更された */
  832.                 main_loop_sub( i );        copy_sw = TRUE;
  833.             };
  834.         };
  835.     } else {
  836.         for( i = 0 ; i < max_new_div ; i++ ) {
  837.             if ( check_file_name( div_new[ i ].file ) == TRUE ) {
  838.                 main_loop_sub( i );
  839.                 /* 以下の1行をコメントアウトした 1993.3.21 
  840.                     copy_sw = TRUE;
  841.                  これによって、「-o:xxxxx」オプションを指定した場合
  842.                 *.old というファイルは出力しないようになった。
  843.                 */
  844.             };
  845.         };
  846.     };
  847.     if ( copy_sw == TRUE ) {
  848.         /* 新ファイルを旧ファイルにコピーする */
  849.         make_old_file( new_file , old_file );
  850.     };
  851.     if ( list_file_sw == TRUE ) {
  852.         printf( "\n部分ファイルのリストを出力 " );
  853.         if ( ( fpi = fopen( list_file_name , "w" ) ) == NULL ) {
  854.             printf( "<%s>をオープンできません" , list_file_name );
  855.             return;
  856.         };
  857.         for ( i = 0 ; i < max_new_div ; i++ ) {
  858.             p1 = div_new[ i ].file;
  859.             while ( *p1 ) *p1++ = tolower( *p1 );
  860.             fprintf( fpi , "%s\n" , div_new[ i ].file );
  861.         };
  862.         fclose( fpi );
  863.         printf( "終了" );
  864.     };
  865. }
  866.  
  867. /* outfile → new_file */
  868. static    void    update_all_file_sub1()
  869. {
  870.     int        sw , div_c ;
  871.     FILE    *fpi , *fpo;
  872.     char    *ptr;
  873.  
  874.     if ( ( fpi = fopen( outfile , "r" ) ) == NULL ) {
  875.         printf( "\n<%s>をオープンできません。" , outfile );
  876.         exit( 1 );
  877.     };
  878.     if ( ( fpo = fopen( new_file , "a" ) ) == NULL ) {
  879.         printf( "\n<%s>をオープンできません。" , new_file );
  880.         exit( 1 );
  881.     };
  882.  
  883.     ptr = outfile;
  884.     while ( *ptr ) *ptr++ = tolower( *ptr );
  885.     printf( "\n<%-13s>を処理します " , outfile );
  886.  
  887.     line_number = 0;
  888.  
  889.     /* 1行目をチェックする */
  890.     fgets( str , MAX_BUFSIZE , fpi );
  891.     if ( isStartLine( str , &sw ) == TRUE ) {
  892.         /* divide_start の行がある */
  893.         div_c = *str;    /* 1桁目を保存しておく */
  894.     } else {
  895.         ptr = last_comma( outfile );
  896.         if ( ptr == outfile ) {                    div_c = '#';
  897.             fprintf( fpo , "# DIVIDE_START=%s\n" , outfile );
  898.         } else if ( strcmp( ptr , ".c" ) == 0 ) {    div_c = '/';
  899.             fprintf( fpo , "/* DIVIDE_START=%s */\n" , outfile );
  900.         } else if ( strcmp( ptr , ".plt" ) == 0 ) {    div_c = '/';
  901.             fprintf( fpo , "/* DIVIDE_START=%s */\n" , outfile );
  902.         } else if ( strcmp( ptr , ".plp" ) == 0 ) {    div_c = '/';
  903.             fprintf( fpo , "/* DIVIDE_START=%s */\n" , outfile );
  904.         } else if ( strcmp( ptr , ".asm" ) == 0 ) {    div_c = ';';
  905.             fprintf( fpo , "; DIVIDE_START=%s\n" , outfile );
  906.         } else if ( strcmp( ptr , ".lnk" ) == 0 ) {    div_c = ';';
  907.             fprintf( fpo , "; -DIVIDE_START=%s\n" , outfile );
  908.         } else if ( strcmp( ptr , ".bat" ) == 0 ) {    div_c = 'R';
  909.             fprintf( fpo , "REM DIVIDE_START=%s\n" , outfile );
  910.         } else {                                    div_c = '/';
  911.             fprintf( fpo , "/* DIVIDE_START=%s */\n" , outfile );
  912.         };
  913.     };
  914.     fprintf( fpo , "%s" , str );    /* 1行目を書き出す */
  915.     line_number++;
  916.  
  917.     /* ファイルの最終行をチェックしながら書き出す */
  918.     sw = FALSE;
  919.     while ( fgets( str , MAX_BUFSIZE , fpi ) != NULL ) {
  920.         if ( isDivideEnd( str ) == TRUE ) {
  921.             sw = TRUE;    break;
  922.         };
  923.         fprintf( fpo , "%s" , str );
  924.         line_number++;
  925.     };
  926.     if ( sw == TRUE ) {
  927.         fprintf( fpo , "%s" , str );
  928.     } else {
  929.         /* devide_end の行を書き出す */
  930.         if ( div_c == '/' ) {
  931.             fprintf( fpo , "/* DIVIDE_END */\n" );
  932.         } else if ( div_c == '#' ) {
  933.             fprintf( fpo , "# DIVIDE_END\n" );
  934.         } else if ( div_c == ';' ) {
  935.             fprintf( fpo , "; DIVIDE_END\n" );
  936.         } else if ( div_c == 'R' ) {
  937.             fprintf( fpo , "REM DIVIDE_END\n" );
  938.         } else {
  939.             fprintf( fpo , "/* DIVIDE_END */\n" );
  940.         };
  941.     };
  942.     fprintf( fpo, "\n" );    /* 1993.8.7 追加 */
  943.     line_number++;
  944.     printf( " %4d 行 終了" , line_number );
  945.     fclose( fpi );
  946.     fclose( fpo );
  947. }
  948.  
  949. /* old_file → new_file */
  950. static    void    update_all_file( int append_sw )
  951. {
  952.             int        done , cnt ;
  953.     struct    ffblk    ffblk;
  954.             char    path[ MAX_FILENAME_LEN ] , *p1 , *p2 ;
  955.  
  956.     /* もし new_file が存在するならば、警告を出す */
  957.     if (    access( new_file , 0 ) == 0
  958.     &&        append_sw == NO
  959.     ) {
  960.         /* ファイルが存在する */
  961.         printf( "\n<%-13s>というファイルがあります。削除してもよろしいですか?"
  962.                 , new_file
  963.         );
  964.         if ( get_yesno_mes() == YES ) {
  965.             remove( new_file );
  966.             printf( "\n 削除しました" );
  967.         } else {
  968.             printf( "\n追加モードで書き込んでもよろしいですか?" );
  969.             if ( get_yesno_mes() == NO ) {
  970.                 printf( "\n 終了します" );        exit( 1 );
  971.             };
  972.         };
  973.     };
  974.  
  975.     strcpy( path , old_file );
  976.     if ( path[2] == ':' ) {        p1 = path + 3;
  977.     } else {                    p1 = path;
  978.     };
  979.     p2 = last_yen( p1 );
  980.     if ( p2 != p1 ) {            *(p2+1) = '\0';
  981.     } else {                    *p2 = '\0';
  982.     };
  983.     cnt = 0;        done = findfirst( old_file , &ffblk , FA_DIREC );
  984.     while ( ! done ) {
  985.         if (    strcmp( ffblk.ff_name , ".." ) != 0
  986.         &&        strcmp( ffblk.ff_name , "."  ) != 0
  987.         ) {
  988.             strcpy( outfile , path );
  989.             strcat( outfile , ffblk.ff_name );
  990.             update_all_file_sub1( );
  991.             cnt++;
  992.         };
  993.         done = findnext( &ffblk );
  994.     };
  995.     printf( "\t%d 個のファイルがありました" , cnt );
  996. }
  997.  
  998. static    void
  999. appendFile( const char *opt, const char *outFile, int append_sw )
  1000. {
  1001.     char    *p;
  1002.  
  1003.     /* -u:xxxxx オプション */
  1004.     /* -a:xxxxx オプション */
  1005.     /* old_file → new_file */
  1006.     if ( strlen( opt ) >= MAX_FILENAME_LEN ) {
  1007.         printf( "検索するファイル名の長さが長すぎます");
  1008.         exit( 1 );
  1009.     };
  1010.     strcpy( old_file , opt );
  1011.     strcpy( new_file , outFile );
  1012.     update_all_file( append_sw );
  1013.     /* *.old ファイルを作る */
  1014.     strcpy( old_file , new_file );    p = last_yen( old_file );
  1015.     if ( p != last_comma(p) ) {        p = last_comma(p);    *p='\0';
  1016.     };
  1017.     strcat( old_file , ".old" );
  1018.     make_old_file( new_file , old_file );
  1019. }
  1020.  
  1021. void    main( int argc , char **argv )
  1022. {
  1023.     char    *p;
  1024.  
  1025.     strcpy( str, *argv );
  1026.  
  1027.     if ( argc <= 1 ) {
  1028.         useage();
  1029.         exit( 1 );
  1030.     };
  1031.     while ( --argc ) {
  1032.         ++argv;
  1033.         if ( **argv == '-' ) {
  1034.             if ( strncmp( *argv , "-u:" , 3 ) == 0 ) {
  1035.                 if ( --argc ) {
  1036.                     p = *argv + 3;    argv++;
  1037.                     appendFile( p, *argv , NO );
  1038.                 } else {        break;
  1039.                 };
  1040.             } else if ( strncmp( *argv , "-a:" , 3 ) == 0 ) {
  1041.                 if ( --argc ) {
  1042.                     p = *argv + 3;    argv++;
  1043.                     appendFile( p, *argv , YES );
  1044.                 } else {        break;
  1045.                 };
  1046.             } else {
  1047.                 set_options( *argv + 1 );
  1048.             };
  1049.         } else {                    main_loop( *argv );
  1050.         };
  1051.     };
  1052.     if ( list_file_sw != FALSE ) fclose( fpl );
  1053.     printf( "\n" );
  1054.     exit( 0 );
  1055. }
  1056.  
  1057. /* DIVIDE_END */
  1058.